/**
 *单属性匀速运动
 * @param obj   需要移动的对象
 * @param attr  属性名称  string 以哪个属性为标准来移动
 * @param target 目标位置 number（需要移动到哪个位置）
 * @param time   移动时间  number（在多少毫秒内移动过去）
 */
function move1(obj,attr,target,time)
{
    //清除上一次的timer，保证只存在一个timer
    clearInterval(obj.timer)
    //获取起点值
    let start=parseInt(getStyle(obj,attr));
    //计算距离
    let distance=target-start;
    //计算一共要走多少步
    let steps=parseInt(time/30);
    //计算步长（即速度）
    let speed=distance/steps;
    let n=0;//n记录当前步数
    //开定时器（为obj定义一个timer属性，使其拥有唯一定时器）
    obj.timer=setInterval(function(){
        n++;
        obj.style[attr]=start+n*speed+"px";
        if(n==steps) {
            clearInterval(obj.timer);
            //stemps是取整的近似值，最终可能有几像素的误差，因此最后进行赋值
            obj.style[attr]=target+"px";
        }
    },30)
}

/**
 * 单属性匀速运动、兼容透明度
 * @param obj    需要移动的对象
 * @param attr   属性名称  string 以哪个属性为标准来移动
 * @param target  目标位置 number（需要移动到哪个位置）/当为透明度时（0-100）半透明50
 * @param time
 */
function move2(obj,attr,target,time)
{
    clearInterval(obj.timer)
    //算距离，将透明度转换为0-100之间的整数，避免小数的近似存储
   start= (attr=="opcity")? parseInt(getStyle(obj,attr)*100):parseInt(getStyle(obj,attr))
    let distance=target-start;
    //计算一共要走多少步
    let steps=parseInt(time/30);
    //计算步长（即速度）
    let speed=distance/steps;
    //开定时器
    let n=0;//n记录当前步数
    obj.timer=setInterval(function(){
        n++;
        if(attr=="opcity")
            //opacity值为0-1，因此需要除以100转换回来
            obj.style.opacity=(start+n*speed)/100;
        else
            obj.style[attr]=start+n*speed+"px";
        if(n==steps) {
            clearInterval(obj.timer);
            if(attr=="opcity")
                obj.style.opacity=target/100;
            else
                obj.style[attr]=target+"px";
        }
    },30)
}

/**
 * 缓冲运动（距离终点越近，速度越小，speed=距离终点的距离/10）
 * @param obj   进行运动的对象
 * @param attr   属性
 * @param target   目标位置
 */
function move3(obj,attr,target){
    //清除上一次的定时器
    clearInterval(obj.timer);
    //获取起点位置
    let start=parseInt(getStyle(obj,attr));
    //缓冲运动速度、距离等都是不确定的，都应该在定时器里面进行计算
    setInterval(function () {
        //target-start为剩余距离，速度等于剩下距离的十分之一，如果大于0（正向运动）则速度向上取整(0.8/1)，如果小于0（反向运动）则速度向下取整（-11.46//-12）
        var speed=target-start>0 ? Math.ceil((target-start)/10):Math.floor((target-start)/10)
        //将下一次的起点设为本次的终点
        start+=speed;
        obj.style[attr]=start+"px";
        //判断终点
        if(start==target) {
            clearInterval(obj.timer)
        }
    },30)
}

/**
 * 缓冲运动，兼容透明度
 * @param obj  进行缓冲运动的对象
 * @param attr  属性名称  string 以哪个属性为标准来移动
 * @param target   目标位置 number（需要移动到哪个位置）/当为透明度时（0-100）半透明50
 */
function move4(obj,attr,target) {
    //清除上一次的定时器
    clearInterval(obj.timer);
    //获取起点位置
    let start;
    if (attr == "opacity")
        start = parseInt(getStyle(obj, "opacity") * 100);
    else
        start = parseInt(getStyle(obj, attr));
    //缓冲运动速度、距离等都是不确定的，都应该在定时器里面进行计算
    setInterval(function () {
        //target-start为剩余距离，速度等于剩下距离的十分之一，如果大于0（正向运动）则速度向上取整(0.8/1)，如果小于0（反向运动）则速度向下取整（-11.46//-12）
        var speed = target - start > 0 ? Math.ceil((target - start) / 10) : Math.floor((target - start) / 10)
        //将下一次的起点设为本次的终点
        start += speed;
        if (attr == "opacity")
            obj.style[attr] = start / 100;
        else
            obj.style[attr] = start + "px";
        //判断终点
        if (start == target) {
            clearInterval(obj.timer)
        }
    }, 30)
}

/**
 * 多属性匀速运动
 * @param obj   元素对象  运动的对象  必须
 * @param endJson  Json对象  需要运动的属性以及终点值  必须
 * @param time  时间（以毫秒为单位） 运动在多少毫秒内完成 必须
 * @param fn    运动完成后是否需要什么操作  非必须
 */
function move5(obj,endJson,time,fn) {
    //清除上一次的定时器
    clearInterval(obj.timer);
    let startJson={};//用于存储起点位置的json
    let speedJson={};//用于存储速度（步长）的json
    let n=0;//用于记录当前步数
     //计算步数
    let steps=parseInt(time/30);
    //获取起点位置,并且计算速度
    for(let key in endJson) {
        startJson[key]=parseInt(getStyle(obj,key));
        speedJson[key]=(endJson[key]-startJson[key])/steps;
    }
    obj.timer=setInterval(function () {
        n++;
        for(let key in endJson){
            obj.style[key]=startJson[key]+n*speedJson[key]+"px";
        }
        //判断终点
        if(n==steps){
            for(let key in endJson) {
                obj.style[key] = endJson[key] + "px";
            }
            clearInterval(obj.timer);
            //调用回调函数（利用逻辑短路）
            fn && fn();
        }
    },30)
}

function move6(obj,endJson,duration,fn) {
    //清除上一次的定时器
    clearInterval(obj.timer);

    let durationJson={
        fast:800,
        normal:1500,
        slow:3000
    };
    if(typeof duration==="string"){
        duration=durationJson[duration];
        if(!duration){
            //diration无效的时候
            duration=duration.normal;
        }
    } else if(typeof duration==="number"){
        duration=duration;
    } else {
        duration=durationJson.normal;
    }

    let startJson={};//用于存储起点位置的json
    let speedJson={};//用于存储速度（步长）的json
    let n=0;//用于记录当前步数
    //计算步数
    let steps=parseInt(duration/30);
    //获取起点位置,并且计算速度
    for(let key in endJson) {
        startJson[key]=parseInt(getStyle(obj,key));
        speedJson[key]=(endJson[key]-startJson[key])/steps;
    }
    obj.timer=setInterval(function () {
        n++;
        for(let key in endJson){
            obj.style[key]=startJson[key]+n*speedJson[key]+"px";
        }
        //判断终点
        if(n==steps){
            for(let key in endJson) {
                obj.style[key] = endJson[key] + "px";
            }
            clearInterval(obj.timer);
            //调用回调函数（利用逻辑短路）
            fn && fn();
        }
    },30)
}

/**
 * 多属性的缓冲运动，兼容透明度，回调函数
 * @param obj  元素对象  运动的对象  必须
 * @param endJson  Json对象  需要运动的属性以及终点值  必须
 * @param fn  运动完成后是否需要什么操作  非必须
 */

function move(obj,endJson,fn){
    //清除上一次的定时器
    clearInterval(obj.timer);
    let startJson={};//用于存储起点位置的json
    let speedJson={};//用于存储速度（步长）的json
    //获取起点位置,并且计算速度
    for(let key in endJson) {
        if(key=="opacity")
            startJson["opacity"]=parseInt(getStyle(obj,"opacity")*100);
        else
            startJson[key]=parseInt(getStyle(obj,key));
    }
    obj.timer=setInterval(function () {
        let flag=false;//用于记录是否达到终点
        //计算剩余距离
        for(let key in endJson){
            let distance=endJson[key]-startJson[key];
            speedJson[key]=distance>0?Math.ceil(distance/10):Math.floor(distance/10);
        }
        for(let key in endJson){
            startJson[key]+=speedJson[key];
            if(key=="opacity")
                obj.style[key]=startJson[key]/100;
            else
                obj.style[key]=startJson[key]+"px";
            if(startJson[key]==endJson[key])
            {
                flag=true;
            }
        }
        //判断终点
        if(flag){
            //到达终点则清除定时器
            clearInterval(obj.timer);
            //调用回调函数（利用逻辑短路）
            fn && fn();
        }
    },30)
}

























































